/****************************************************************************
 * Copyright (C) 2012
 * by Dj_Skual
 *
 * This software is provided 'as-is', without any express or implied
 * warranty. In no event will the authors be held liable for any
 * damages arising from the use of this software.
 *
 * Permission is granted to anyone to use this software for any
 * purpose, including commercial applications, and to alter it and
 * redistribute it freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you
 * must not claim that you wrote the original software. If you use
 * this software in a product, an acknowledgment in the product
 * documentation would be appreciated but is not required.
 *
 * 2. Altered source versions must be plainly marked as such, and
 * must not be misrepresented as being the original software.
 *
 * 3. This notice may not be removed or altered from any source
 * distribution.
 *
 * TplFile.cpp
 *
 * for SaveGame Manager GX 2012
 ***************************************************************************/
#include <malloc.h>
#include <string.h>

#include "TplFile.h"
 
TplFile::TplFile(u8* mem, u32 ImgOffset, u32 PalOffset, u8 fmt, u8 Type)
{
	data = NULL;
	type = Type;
	imgOffset = ImgOffset;
	palOffset = PalOffset;
	format = fmt;
	if(type == TPL_WII_ICON || type == TPL_WII_BANNER)
		format = TPL_FMT_RGB;
	
	fileHeader = new TPL_FileHeader();
	memset(fileHeader, 0, sizeof(TPL_FileHeader));
	fileHeader->magic = 0x0020af30;
	fileHeader->num_textures = 0x01;
	fileHeader->offset_img_table = 0x0C;
	
	offsetTable = new TPL_ImageOffsetTable();
	memset(offsetTable, 0, sizeof(TPL_ImageOffsetTable));
	
	paletteHeader = new TPL_PaletteHeader();
	memset(paletteHeader, 0, sizeof(TPL_PaletteHeader));
	paletteHeader->entry_count = 0x01;
	paletteHeader->palette_format = GX_TL_RGB5A3;
	
	imageHeader = new TPL_ImageHeader();
	memset(imageHeader, 0, sizeof(TPL_ImageHeader));
	imageHeader->wrap_s = GX_CLAMP;
	imageHeader->wrap_t = GX_CLAMP;
	
	SetHeader(mem);
}

TplFile::~TplFile()
{
	if(data != NULL)
	{
		free(data);
		data = NULL;
	}
	
	if(fileHeader) free(fileHeader);
	if(offsetTable) free(offsetTable);
	if(paletteHeader) free(paletteHeader);
	if(imageHeader) free(imageHeader);
	fileHeader = NULL;
	offsetTable = NULL;
	paletteHeader = NULL;
	imageHeader = NULL;
}

void TplFile::SetHeader(u8* mem)
{
	offsetTable->image_header_offset = ((format == TPL_FMT_RGB) ? 0x14 : 0x20);
	offsetTable->palette_header_offset = ((format == TPL_FMT_RGB) ? 0x00 : 0x14);
	
	imageHeader->image_format = ((format == TPL_FMT_RGB) ? GX_TF_RGB5A3 : GX_TF_CI8);
	imageHeader->image_data_offset = HeaderSize();
	
	paletteHeader->palette_data_offset = (HeaderSize() + ImgSize());
	
	switch(type)
	{
		case TPL_GC_ICON:
			imageHeader->height = 0x20;
			imageHeader->width = 0x20;
			break;
		case TPL_GC_BANNER:
			imageHeader->height = 0x20;
			imageHeader->width = 0x60;
			break;
		case TPL_WII_ICON:
			imageHeader->height = 0x30;
			imageHeader->width = 0x30;
			break;
		case TPL_WII_BANNER:
		default:
			imageHeader->height = 0x40;
			imageHeader->width = 0xc0;
			break;
	}
	
	SetDatas(mem);
}

void TplFile::SetDatas(u8* mem)
{
	data = (u8*)memalign(32, Size());
	memset(data, 0, Size());
	
	memcpy(data, fileHeader, sizeof(TPL_FileHeader));
	u32 offset = sizeof(TPL_FileHeader);
	memcpy(data + offset, offsetTable, sizeof(TPL_ImageOffsetTable));
	offset += sizeof(TPL_ImageOffsetTable);
	if(format == TPL_FMT_CI8)
	{
		memcpy(data + offset, paletteHeader, sizeof(TPL_PaletteHeader));
		offset += sizeof(TPL_PaletteHeader);
	}
	memcpy(data + offset, imageHeader, sizeof(TPL_ImageHeader));
	
	memcpy(data + HeaderSize(), mem + imgOffset, ImgSize());
	if(format == TPL_FMT_CI8)
		memcpy(data + (HeaderSize() + ImgSize()), mem + palOffset, PalSize());
}

u32 TplFile::Size()
{
	int size = 0;
	
	size += HeaderSize();
	size += ImgSize();
	size += PalSize();
	
	return size;
}

u32 TplFile::HeaderSize()
{
	return ((format == TPL_FMT_RGB) ? 0x40 : 0x60);
}

u32 TplFile::ImgSize()
{
	switch(type)
	{
		case TPL_GC_ICON:
			return ((format == TPL_FMT_RGB) ? 0x0800 : 0x0400);
		case TPL_GC_BANNER:
			return ((format == TPL_FMT_RGB) ? 0x1800 : 0x0c00);
		case TPL_WII_ICON:
			return 0x1200;
		case TPL_WII_BANNER:
		default:
			return 0x6000;
	}
	
	return 0;
}

u32 TplFile::PalSize()
{
	return ((format == TPL_FMT_RGB) ? 0x0000 : 0x0200);
}

u8* TplFile::Datas()
{
	return data;
}
